import time
from flask import Blueprint
from settings import FeeRate
from orm import Status, Request,Log
from peewee import DoesNotExist
from threading import Thread
from orm import Room

class monitor:
    status = None
    out_temp = 0  #外部温度
    rate = 10  # 变化速率1/rate,低速风每分钟改变1度,代表一分钟代表实际多长时间
    cur_temp = 0
    target_temp = 0
    speed = 0
    flag = False
    switch = False
    time = 0    # 上次计算温度的时间

    last_req = 0
    def syntax(self):
        # 导入状态中的目标温度和风速
        self.status = Status.get(Status.id == self.status.id)
        self.target_temp = self.status.target_temp
        self.speed = self.status.speed

    def update(self):
        # 将当前温度更新状态表
        self.status.cur_temp = self.cur_temp
        if self.cur_temp == self.target_temp: self.status.speed = 0
        self.status.save()

    def request(self):
        # 空调资源请求，风速默认为2
        try:
            # 如果已有请求，则将请求的风速和请求温度改变
            req = Request.get_by_id(self.status.id)
            req.speed = 2
            req.temp = round(self.target_temp)
            req.save()
            # 生成请求的详单
            Log(slave_id=req.slave_id,
                card_id=self.status.card_id,
                cur_temp=self.status.cur_temp,
                target_temp=req.temp,
                speed=req.speed,
                req_time=time.strftime('%Y-%m-%d %H:%M:%S')).save()
        except DoesNotExist:
            try:
                Request(
                    slave_id=self.status.id, speed=2,
                    temp=round(self.target_temp)).save()
                # 生成一条请求的详单
                Log(slave_id=self.status.id,
                    card_id=self.status.card_id,
                    cur_temp=self.status.cur_temp,
                    target_temp=round(self.target_temp),
                    speed=2,
                    req_time=time.strftime('%Y-%m-%d %H:%M:%S')).save()                
            except:
                pass    

    def init(self, id, out_temp):
        self.status = Status.get(Status.id == id)
        self.syntax()
        self.cur_temp = self.out_temp = out_temp    #   将当前温度设为室内温度
        self.update()   
        self.time = time.time()

    def run(self):
        while self.flag:
            # print('温度计算中')
            during=0
            if (time.time() - self.time > 1/6):
                # 导入目标温度和风速
                self.syntax()
                # 存储当前温度
                pre_temp = self.cur_temp
                if (self.speed != 0):
                    a = self.speed * self.rate
                    if (self.target_temp > self.cur_temp):
                        x = 1/a
                        during = time.time() - self.time
                        self.cur_temp = min(self.cur_temp+during*x,self.target_temp)
                    elif (self.target_temp < self.cur_temp):
                        x = 1/a
                        during = time.time() - self.time
                        self.cur_temp = max(self.cur_temp-during*x,self.target_temp)

                # 回温程序
                elif (self.cur_temp != self.out_temp):
                    a = 1/(2*self.rate)   # 每分钟变化0.5度
                    if (self.out_temp > self.cur_temp):
                        during = time.time() - self.time
                        self.cur_temp = min(self.cur_temp+a*during,self.out_temp)

                    if (self.out_temp < self.cur_temp):
                        during = time.time() - self.time
                        self.cur_temp = max(self.cur_temp-a*during,self.out_temp)

                    if (self.switch):
                        # 如果当前温度与目标温度相差1度则启动空调
                        if (abs(self.cur_temp - self.target_temp) > 1
                                and time.time() - self.last_req > 1):
                            self.last_req = time.time()
                            self.request()

                #   如果不需要启动回温程序,已经到达当前室温，请求开机
                elif (self.cur_temp == self.out_temp and self.switch):
                    if (time.time() - self.last_req > 1):
                        self.last_req = time.time()
                        self.request()

                self.update()
                # 计算费用
                self.cost(abs(self.cur_temp-pre_temp))
                self.time = time.time()
                time.sleep(1)

	#以秒为单位计算从机的消费金额并更新到从机状态
    def cost(self,change_temp):
            # self.syntax()
            if self.speed!=0:
                cost = FeeRate*change_temp
                #更新从控机状态
                self.status.amount += cost
                self.status.save() 

ac = [monitor() for i in range(5)]

threadList = [[] for i in range(5)]

monitor = Blueprint('monitor', __name__)


@monitor.route('/init/<id>/<init>')
def init(id, init):
    print(f'初始化房间{id}温度为:{init}')
    num = int(id) - 1   # 从机号
    if not ac[num].flag:
        ac[num].init(int(id), int(init))
        ac[num].flag = True
    else:
        ac[num].cur_temp = ac[num].out_temp = int(init)
        ac[num].status = Status.get(Status.id == id)
    threadList[num] = Thread(target=ac[num].run) 
    threadList[num].start()
    try:
        Room.insert({'id':id,'open_time':time.strftime('%Y-%m-%d %H:%M:%S')}).execute()
    except Exception as e :
        print(e)
        print('已经初始化')
    return 'ok'



@monitor.route('/open/<id>')
def open(id):
    num = int(id) - 1
    ac[num].flag = True 
    ac[num].switch = True
    Status.update({Status.open:1}).where(Status.id==id).execute()
    # status = Status.get(Status.id==id)
    # # 生成开机请求的详单
    # Log(slave_id=id,
    #     card_id=status.card_id,
    #     cur_temp=status.cur_temp,
    #     target_temp=status.target_temp,
    #     speed=2,
    #     req_time=time.strftime('%Y-%m-%d %H:%M:%S')).save()
    return 'ok'


@monitor.route('/close/<id>')
def close(id):
    num = int(id) - 1
    ac[num].switch = False
    Status.update({Status.open:0}).where(Status.id==id).execute()
    return 'ok'


@monitor.route('/destroy/<id>')
def destroy(id):
    num = int(id) - 1
    ac[num].flag = False
    try:    
        Room.update({Room.close_time:time.strftime('%Y-%m-%d %H:%M:%S')}).where(Room.id==id).execute()
    except:
        print('退房失败！')

# @monitor.route('/test/<id>')
# def test(id):
#     print("重定位网址逻辑")
#     print(id)
#     return 'ok'

# if __name__=="__main__":
